﻿namespace YidanSoft.Library.EditorUtility.WinControls
{
    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.Runtime.InteropServices;
    using System.Threading;
    using System.Windows.Forms;
    using YidanSoft.Library.EditorUtility.General;
    using YidanSoft.Library.EditorUtility.Win32;

    public class ColorPickerDropDown : Form
    {
        private ColorChangeEventHandler ColorChanged;
        private Container components = null;
        private Color currentColor;
        private int currentCustomColorIndex = 0;
        private const int CUSTOM_COLOR_HEIGHT = 20;
        private const int CUSTOM_COLOR_WIDTH = 20;
        private const int CUSTOM_COLORS_COUNT = 0x40;
        private const int CUSTOM_COLORS_HORIZ_ITEMS = 8;
        private const int CUSTOM_COLORS_VERT_ITEMS = 8;
        private static Color[] customColors = new Color[] { 
            Color.FromArgb(0xff, 0xff, 0xff), Color.FromArgb(0xe0, 0xe0, 0xe0), Color.FromArgb(0xc0, 0xc0, 0xc0), Color.FromArgb(0x80, 0x80, 0x80), Color.FromArgb(0x40, 0x40, 0x40), Color.FromArgb(0, 0, 0), Color.White, Color.White, Color.FromArgb(0xff, 0xc0, 0xc0), Color.FromArgb(0xff, 0x80, 0x80), Color.FromArgb(0xff, 0, 0), Color.FromArgb(0xc0, 0, 0), Color.FromArgb(0x80, 0, 0), Color.FromArgb(0x40, 0, 0), Color.White, Color.White, 
            Color.FromArgb(0xff, 0xe0, 0xc0), Color.FromArgb(0xff, 0xc0, 0x80), Color.FromArgb(0xff, 0x80, 0), Color.FromArgb(0xc0, 0x40, 0), Color.FromArgb(0x80, 0x40, 0), Color.FromArgb(0x80, 0x40, 0x40), Color.White, Color.White, Color.FromArgb(0xff, 0xff, 0xc0), Color.FromArgb(0xff, 0xff, 0x80), Color.FromArgb(0xff, 0xff, 0), Color.FromArgb(0xc0, 0xc0, 0), Color.FromArgb(0x80, 0x80, 0), Color.FromArgb(0x40, 0x40, 0), Color.White, Color.White, 
            Color.FromArgb(0xc0, 0xff, 0xc0), Color.FromArgb(0x80, 0xff, 0x80), Color.FromArgb(0, 0xff, 0), Color.FromArgb(0, 0xc0, 0), Color.FromArgb(0, 0x80, 0), Color.FromArgb(0, 0x40, 0), Color.White, Color.White, Color.FromArgb(0xc0, 0xff, 0xff), Color.FromArgb(0x80, 0xff, 0xff), Color.FromArgb(0, 0xff, 0xff), Color.FromArgb(0, 0xc0, 0xc0), Color.FromArgb(0, 0x80, 0x80), Color.FromArgb(0, 0x40, 0x40), Color.White, Color.White, 
            Color.FromArgb(0xc0, 0xc0, 0xff), Color.FromArgb(0x80, 0x80, 0xff), Color.FromArgb(0, 0, 0xff), Color.FromArgb(0, 0, 0xc0), Color.FromArgb(0, 0, 0x80), Color.FromArgb(0, 0, 0x40), Color.White, Color.White, Color.FromArgb(0xff, 0xc0, 0xff), Color.FromArgb(0xff, 0x80, 0xff), Color.FromArgb(0xff, 0, 0xff), Color.FromArgb(0xc0, 0, 0xc0), Color.FromArgb(0x80, 0, 0x80), Color.FromArgb(0x40, 0, 0x40), Color.White, Color.White
         };
        private TabPage customColorsPage;
        private static Rectangle[] customColorsRects = new Rectangle[0x40];
        private bool customColorsRectsSaved = false;
        private bool exitLoop = false;
        private bool rightButtonDown = false;
        private ColorListBox systemColorsList = new ColorListBox();
        private TabPage systemColorsPage;
        private TabControl tabControl;
        private const int USED_COLS = 8;
        private const int USED_ROWS = 6;
        private ColorListBox webColorsList = new ColorListBox();
        private TabPage webColorsPage;

        public event ColorChangeEventHandler ColorChanged
        {
            add
            {
                ColorChangeEventHandler handler2;
                ColorChangeEventHandler colorChanged = this.ColorChanged;
                do
                {
                    handler2 = colorChanged;
                    ColorChangeEventHandler handler3 = (ColorChangeEventHandler) Delegate.Combine(handler2, value);
                    colorChanged = Interlocked.CompareExchange<ColorChangeEventHandler>(ref this.ColorChanged, handler3, handler2);
                }
                while (colorChanged != handler2);
            }
            remove
            {
                ColorChangeEventHandler handler2;
                ColorChangeEventHandler colorChanged = this.ColorChanged;
                do
                {
                    handler2 = colorChanged;
                    ColorChangeEventHandler handler3 = (ColorChangeEventHandler) Delegate.Remove(handler2, value);
                    colorChanged = Interlocked.CompareExchange<ColorChangeEventHandler>(ref this.ColorChanged, handler3, handler2);
                }
                while (colorChanged != handler2);
            }
        }

        public ColorPickerDropDown()
        {
            base.StartPosition = FormStartPosition.Manual;
            this.InitializeComponent();
            this.InitializeListBoxes();
        }

        private void ColorPickerDropDown_VisibleChanged(object sender, EventArgs e)
        {
            if (base.Visible)
            {
                int customColorIndex;
                if (!this.currentColor.IsNamedColor)
                {
                    customColorIndex = this.GetCustomColorIndex(this.currentColor);
                    this.currentCustomColorIndex = customColorIndex;
                    this.tabControl.SelectedIndex = 0;
                }
                else if (this.GetSystemColorIndex(this.currentColor, out customColorIndex))
                {
                    this.tabControl.SelectedIndex = 2;
                }
                else if (this.GetWebColorIndex(this.currentColor, out customColorIndex))
                {
                    this.tabControl.SelectedIndex = 1;
                }
            }
        }

        private void customColorsPage_Click(object sender, EventArgs e)
        {
            ColorChangeArgs args;
            Point mousePosition = Control.MousePosition;
            Point p = this.customColorsPage.PointToClient(mousePosition);
            if (this.rightButtonDown)
            {
                int index = -1;
                if (this.IsSpareColor(p, ref index))
                {
                    CustomColorDlg dlg = new CustomColorDlg();
                    dlg.CurrentColor = customColors[index];
                    if (dlg.ShowDialog(this) == DialogResult.OK)
                    {
                        customColors[index] = dlg.CurrentColor;
                        args = new ColorChangeArgs(dlg.CurrentColor, "CustomTab");
                        this.OnColorChanged(args);
                    }
                }
                this.rightButtonDown = false;
            }
            else
            {
                Graphics g = this.customColorsPage.CreateGraphics();
                Color color = ColorUtil.ColorFromPoint(g, p.X, p.Y);
                g.Dispose();
                Color newColor = this.FindCustomColor(p);
                if (newColor != Color.Empty)
                {
                    args = new ColorChangeArgs(newColor, "CustomTab");
                    this.OnColorChanged(args);
                    this.exitLoop = true;
                    base.Visible = false;
                }
            }
        }

        private void customColorsPage_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                this.rightButtonDown = true;
            }
        }

        private void customColorsPage_Paint(object sender, PaintEventArgs e)
        {
            Graphics graphics = e.Graphics;
            Rectangle clientRectangle = this.customColorsPage.ClientRectangle;
            clientRectangle.Inflate(-2, -2);
            int num = 3;
            for (int i = 0; i < 8; i++)
            {
                int x = (clientRectangle.Left + (20 * i)) + (i * num);
                int top = clientRectangle.Top;
                for (int j = 0; j < 8; j++)
                {
                    top = (clientRectangle.Top + (20 * j)) + (j * num);
                    int index = (i * 8) + j;
                    ControlPaint.DrawBorder3D(graphics, x, top, 20, 20, Border3DStyle.Sunken);
                    graphics.FillRectangle(new SolidBrush(customColors[index]), x + 1, top + 1, 0x12, 0x12);
                    if (!this.customColorsRectsSaved)
                    {
                        customColorsRects[index] = new Rectangle(x + 1, top + 1, 0x12, 0x12);
                    }
                    if (this.currentCustomColorIndex == index)
                    {
                        Rectangle r = new Rectangle(x - 1, top - 1, 0x17, 0x17);
                        r = this.customColorsPage.RectangleToScreen(r);
                        ControlPaint.DrawReversibleFrame(r, SystemColors.Control, FrameStyle.Thick);
                    }
                }
            }
            this.customColorsRectsSaved = true;
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing && (this.components != null))
            {
                this.components.Dispose();
            }
            base.Dispose(disposing);
        }

        private Color FindCustomColor(Point point)
        {
            Color empty = Color.Empty;
            for (int i = 0; i < 0x40; i++)
            {
                if (customColorsRects[i].Contains(point))
                {
                    empty = customColors[i];
                    this.currentCustomColorIndex = i;
                    return empty;
                }
            }
            return empty;
        }

        private int GetCustomColorIndex(Color color)
        {
            for (int i = 0; i < 0x40; i++)
            {
                if (customColors[i].Equals(color))
                {
                    return i;
                }
            }
            return -1;
        }

        private bool GetSystemColorIndex(Color color, out int index)
        {
            index = -1;
            string name = color.Name;
            index = this.systemColorsList.FindStringExact(name);
            if (index != -1)
            {
                this.systemColorsList.SelectedIndex = index;
                return true;
            }
            return false;
        }

        private bool GetWebColorIndex(Color color, out int index)
        {
            index = -1;
            string name = color.Name;
            index = this.webColorsList.FindStringExact(name);
            if (index != -1)
            {
                this.webColorsList.SelectedIndex = index;
                return true;
            }
            return false;
        }

        private void InitializeComponent()
        {
            this.tabControl = new TabControl();
            this.customColorsPage = new TabPage();
            this.webColorsPage = new TabPage();
            this.systemColorsPage = new TabPage();
            this.tabControl.SuspendLayout();
            base.SuspendLayout();
            this.tabControl.Controls.AddRange(new Control[] { this.customColorsPage, this.webColorsPage, this.systemColorsPage });
            this.tabControl.Cursor = Cursors.Default;
            this.tabControl.Location = new Point(0, 4);
            this.tabControl.Name = "tabControl";
            this.tabControl.SelectedIndex = 0;
            this.tabControl.Size = new Size(200, 0xbc);
            this.tabControl.TabIndex = 0;
            this.tabControl.SelectedIndexChanged += new EventHandler(this.tabControl_SelectedIndexChanged);
            this.customColorsPage.BorderStyle = BorderStyle.FixedSingle;
            this.customColorsPage.Location = new Point(4, 0x16);
            this.customColorsPage.Name = "customColorsPage";
            this.customColorsPage.Size = new Size(0xc0, 0xa2);
            this.customColorsPage.TabIndex = 0;
            this.customColorsPage.Text = "Custom";
            this.customColorsPage.Click += new EventHandler(this.customColorsPage_Click);
            this.customColorsPage.Paint += new PaintEventHandler(this.customColorsPage_Paint);
            this.customColorsPage.MouseDown += new MouseEventHandler(this.customColorsPage_MouseDown);
            this.webColorsPage.BorderStyle = BorderStyle.FixedSingle;
            this.webColorsPage.Location = new Point(4, 0x16);
            this.webColorsPage.Name = "webColorsPage";
            this.webColorsPage.Size = new Size(0xc0, 0xa2);
            this.webColorsPage.TabIndex = 1;
            this.webColorsPage.Text = "Web";
            this.systemColorsPage.BorderStyle = BorderStyle.FixedSingle;
            this.systemColorsPage.Location = new Point(4, 0x16);
            this.systemColorsPage.Name = "systemColorsPage";
            this.systemColorsPage.Size = new Size(0xc0, 0xa2);
            this.systemColorsPage.TabIndex = 2;
            this.systemColorsPage.Text = "System";
            base.AutoScale = false;
            this.AutoScaleBaseSize = new Size(5, 13);
            base.ClientSize = new Size(0xc6, 0xd7);
            base.Controls.AddRange(new Control[] { this.tabControl });
            this.ForeColor = SystemColors.Control;
            base.FormBorderStyle = FormBorderStyle.None;
            base.Name = "ColorPickerDropDown";
            base.SizeGripStyle = SizeGripStyle.Hide;
            base.VisibleChanged += new EventHandler(this.ColorPickerDropDown_VisibleChanged);
            this.tabControl.ResumeLayout(false);
            base.ResumeLayout(false);
        }

        private void InitializeListBoxes()
        {
            this.webColorsList.ColorArray = ColorUtil.KnownColorNames;
            this.systemColorsList.ColorArray = ColorUtil.SystemColorNames;
            this.customColorsPage.BorderStyle = BorderStyle.FixedSingle;
            this.customColorsPage.Location = new Point(4, 0x16);
            this.customColorsPage.Name = "customColorsPage";
            this.customColorsPage.Size = new Size(0xb2, 0xbc);
            this.customColorsPage.TabIndex = 0;
            this.customColorsPage.Text = "Custom";
            this.customColorsPage.Click += new EventHandler(this.customColorsPage_Click);
            this.customColorsPage.Paint += new PaintEventHandler(this.customColorsPage_Paint);
            this.customColorsPage.MouseDown += new MouseEventHandler(this.customColorsPage_MouseDown);
            this.webColorsList.BorderStyle = BorderStyle.None;
            this.webColorsList.Location = new Point(6, 4);
            this.webColorsList.Name = "webColorsList";
            this.webColorsList.Size = new Size(0xb2, 0xbc);
            this.webColorsList.TabIndex = 0;
            this.webColorsList.Click += new EventHandler(this.webColorsList_Click);
            this.webColorsPage.Controls.AddRange(new Control[] { this.webColorsList });
            this.systemColorsList.BorderStyle = BorderStyle.None;
            this.systemColorsList.Location = new Point(8, 8);
            this.systemColorsList.Name = "systemColorsList";
            this.systemColorsList.Size = new Size(0xb2, 0xbc);
            this.systemColorsList.TabIndex = 0;
            this.systemColorsList.Click += new EventHandler(this.systemColorsList_Click);
            this.systemColorsPage.Controls.AddRange(new Control[] { this.systemColorsList });
        }

        private bool IsChild(IntPtr hWnd)
        {
            return ((this.tabControl.Handle == hWnd) || ((this.webColorsList.Handle == hWnd) || ((this.systemColorsList.Handle == hWnd) || ((this.customColorsPage.Handle == hWnd) || ((this.webColorsPage.Handle == hWnd) || (this.systemColorsPage.Handle == hWnd))))));
        }

        private bool IsSpareColor(Point p, ref int index)
        {
            for (int i = 0; i < 8; i++)
            {
                for (int j = 6; j < 8; j++)
                {
                    if (customColorsRects[(i * 8) + j].Contains(p))
                    {
                        index = (i * 8) + j;
                        this.currentCustomColorIndex = index;
                        return true;
                    }
                }
            }
            return false;
        }

        protected void OnColorChanged(ColorChangeArgs e)
        {
            this.currentColor = e.NewColor;
            if (this.ColorChanged != null)
            {
                this.ColorChanged(this, e);
            }
        }

        protected override void OnDeactivate(EventArgs e)
        {
            base.OnDeactivate(e);
            this.exitLoop = true;
            base.Visible = false;
        }

        protected override void OnPaint(PaintEventArgs pe)
        {
            base.OnPaint(pe);
            Graphics graphics = pe.Graphics;
            Rectangle clientRectangle = base.ClientRectangle;
            graphics.DrawRectangle(Pens.Black, clientRectangle.Left, clientRectangle.Top, clientRectangle.Width - 1, clientRectangle.Height - 1);
        }

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            Rectangle clientRectangle = base.ClientRectangle;
            this.tabControl.Left = 2;
            this.tabControl.Top = 2;
            this.tabControl.Width = clientRectangle.Width - 3;
            this.tabControl.Height = clientRectangle.Height - 3;
            this.customColorsPage.Left = 0;
            this.customColorsPage.Top = 0;
            this.customColorsPage.Width = clientRectangle.Width - 3;
            this.customColorsPage.Height = clientRectangle.Height - 3;
            this.webColorsPage.Left = 0;
            this.webColorsPage.Top = 0;
            this.webColorsPage.Width = clientRectangle.Width - 3;
            this.webColorsPage.Height = clientRectangle.Height - 3;
            this.webColorsList.Left = 0;
            this.webColorsList.Top = 0;
            this.webColorsList.Width = clientRectangle.Width - 15;
            this.webColorsList.Height = clientRectangle.Height - 0x1a;
            this.systemColorsPage.Left = 0;
            this.systemColorsPage.Top = 0;
            this.systemColorsPage.Width = clientRectangle.Width - 3;
            this.systemColorsPage.Height = clientRectangle.Height - 3;
            this.systemColorsList.Left = 0;
            this.systemColorsList.Top = 0;
            this.systemColorsList.Width = clientRectangle.Width - 15;
            this.systemColorsList.Height = clientRectangle.Height - 0x1a;
        }

        private void StartPeekMessageLoop()
        {
            YidanSoft.Library.EditorUtility.Win32.MSG msg = new YidanSoft.Library.EditorUtility.Win32.MSG();
            bool flag = false;
            while (!this.exitLoop)
            {
                if (WindowsAPI.WaitMessage())
                {
                    while (!this.exitLoop && WindowsAPI.PeekMessage(ref msg, 0, 0, 0, 0))
                    {
                        if (((((msg.message == 0x201) || (msg.message == 0x207)) || ((msg.message == 0x204) || (msg.message == 0xa1))) || (msg.message == 0xa7)) || (msg.message == 0xa4))
                        {
                            if (!(!(msg.hwnd != base.Handle) || this.IsChild(msg.hwnd)))
                            {
                                this.exitLoop = true;
                                flag = true;
                            }
                        }
                        else if ((msg.message == 0x200) && !(!(msg.hwnd != base.Handle) || this.IsChild(msg.hwnd)))
                        {
                            YidanSoft.Library.EditorUtility.Win32.MSG msg2 = new YidanSoft.Library.EditorUtility.Win32.MSG();
                            WindowsAPI.GetMessage(ref msg2, 0, 0, 0);
                            flag = true;
                        }
                        if (!flag)
                        {
                            if (WindowsAPI.GetMessage(ref msg, 0, 0, 0))
                            {
                                WindowsAPI.TranslateMessage(ref msg);
                                WindowsAPI.DispatchMessage(ref msg);
                            }
                        }
                        else
                        {
                            flag = false;
                        }
                    }
                }
            }
        }

        private void systemColorsList_Click(object sender, EventArgs e)
        {
            Color newColor = Color.FromName(this.systemColorsList.Text);
            this.currentColor = newColor;
            ColorChangeArgs args = new ColorChangeArgs(newColor, "SystemTab");
            this.OnColorChanged(args);
            this.exitLoop = true;
            base.Visible = false;
        }

        private void tabControl_SelectedIndexChanged(object sender, EventArgs e)
        {
            switch (this.tabControl.SelectedIndex)
            {
                case 1:
                    this.webColorsList.Focus();
                    break;

                case 2:
                    this.systemColorsList.Focus();
                    break;
            }
        }

        private void webColorsList_Click(object sender, EventArgs e)
        {
            ColorChangeArgs args = new ColorChangeArgs(Color.FromName(this.webColorsList.Text), "WebTab");
            this.OnColorChanged(args);
            this.exitLoop = true;
            base.Visible = false;
        }

        protected override void WndProc(ref Message m)
        {
            bool flag = true;
            if (m.Msg == 15)
            {
                flag = false;
                base.WndProc(ref m);
                this.exitLoop = false;
                Application.DoEvents();
                this.StartPeekMessageLoop();
            }
            if (flag)
            {
                base.WndProc(ref m);
            }
        }

        public Color CurrentColor
        {
            set
            {
                this.currentColor = value;
            }
        }
    }
}

